package com.yc.login.web;

import com.yc.login.LoginProperties;
import com.yc.login.bean.Result;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;

@RestController
public class LoginAction {

    @Resource
    LoginProperties properties;

    @Resource
    JdbcTemplate jdbc;

    @PostMapping("login")
    public Result login(String username, String password, HttpSession session){
        // 验证用户输入
        if (username == null || username.trim().isEmpty()){
            return new Result(0, "请输入用户名", null);
        }
        if (password == null || password.trim().isEmpty()){
            return new Result(0, "请输入密码", null);
        }
        // 构造sql语句
        String sql = "select * from %s where %s=? and %s=?";
        sql = String.format(sql, properties.getUserTable(),
                properties.getNameColumn(),
                properties.getPwdColumn());
        // 执行查询
        List<Map<String, Object>> list = jdbc.queryForList(sql, username, password);
        // 判断查询结果
        if (list.isEmpty()){
            return new Result(0, "用户名或密码错误", null);
        } else if (list.size() > 1){
            return new Result(0, "业务异常，请联系管理员！", null);
        } else {
            // 返回结果
            Map<String, Object> user = list.get(0);
            session.setAttribute("loginedUser", user);
            return new Result(1, "登录成功！", user);
        }
    }


    @GetMapping("getLoginedUser")
    public Result getLoginedUser(@SessionAttribute(required = false) Object loginedUser){
        if (loginedUser==null){
            return new Result(0, "未登录", null);
        } else {
            return new Result(1, "已登录", loginedUser);
        }
    }

    @GetMapping("logout")
    public Result logout(HttpSession session){
        session.invalidate();
        return new Result(1, "已退出", null);
    }

    @PostMapping("setpwd")
    public Result setpwd(String oldPwd, String newPwd, String rePwd,
                         @SessionAttribute(required = false) Map<String, Object> loginedUser){
        if (loginedUser==null){
            return new Result(0, "请先登录系统！", null);
        }
        if (oldPwd == null || oldPwd.trim().isEmpty()){
            return new Result(0,"请输入原密码", null);
        }
        String pwd = (String) loginedUser.get(properties.getPwdColumn());
        if (!pwd.equals(oldPwd)){
            return new Result(0, "原密码输入错误", null);
        }
        if (newPwd == null || newPwd.trim().isEmpty()){
            return new Result(0,"请输入新密码", null);
        }
        if (rePwd == null || rePwd.trim().isEmpty()){
            return new Result(0,"请确认密码", null);
        }
        if (!newPwd.equals(rePwd)){
            return new Result(0,"两次输入的密码不一致", null);
        }

        loginedUser.put(properties.getPwdColumn(), newPwd);

        String sql = "update %s set %s=? where %s=? and %s=?";
        sql = String.format(sql, properties.getUserTable(),
                properties.getPwdColumn(),
                properties.getNameColumn(),
                properties.getPwdColumn());
        String name = (String) loginedUser.get(properties.getNameColumn());
        jdbc.update(sql, newPwd, name, oldPwd);
        return new Result(1, "密码修改成功", null);
    }

    /**
     * 用户重置密码
     * 1. 前置条件：用户忘记密码，在未登录状态
     * 2.提供用户输入用户名的界面，输入用户名，后台查询用户信息
     * 3. 向用户的邮箱地址发送验证码邮件
     * 4. 用户输入验证码和新密码，完成密码重置
     */

    @Resource
    private JavaMailSender mailSender;

    // 忘记密码
    @GetMapping("forgetPwd")
    public Result forget(String name, HttpSession session){
        // 根据用户名查询用户信息
        String sql = "select * from %s where %s=?";
        sql = String.format(sql, properties.getUserTable(),
                properties.getNameColumn());
        try {
            Map<String, Object> user = jdbc.queryForMap(sql, name);
            String email = (String) user.get(properties.getEmailColumn());
            String title = "重置密码文件已发送验证邮件";
            String text = "重置密码的验证码是: ";
            String vcode = System.currentTimeMillis() + "";
            vcode = vcode.substring(vcode.length() - 4); // 截取后四位
            text += vcode;
            send(properties.getFromEmail(), email, title, text);
            session.setAttribute("forget_vcode", vcode);
            session.setAttribute("forget_name", name);
            return new Result(1, "验证码已发送到您的邮箱", null);
        } catch (DataAccessException e){
            e.printStackTrace();
            return new Result(0, "没有该用户信息", null);
        } catch (MessagingException e){
            return new Result(0, "验证码发送失败", null);
        }
    }

    // 重置密码
    @PostMapping("resetPwd")
    public Result resetPwd(String vcode, String newPwd, String rePwd,
                           @SessionAttribute("forget_vcode") String scode,
                           @SessionAttribute("forget_name") String name){
        if (vcode == null || vcode.trim().isEmpty()){
            return new Result(0, "请输入验证码", null);
        }
        if (!scode.equals(vcode)){
            return new Result(0,"验证码输入错误！", null);
        }
        if (newPwd == null || newPwd.trim().isEmpty()){
            return new Result(0, "请输入新密码", null);
        }
        if (!newPwd.equals(rePwd)){
            return new Result(0,"两次输入的密码不一致！", null);
        }

        String sql = "update %s set %s=? where %s=?";
        sql = String.format(sql, properties.getUserTable(),
                properties.getPwdColumn(),
                properties.getNameColumn());
        jdbc.update(sql, newPwd, name);
        return new Result(1,"密码重置成功！", null);
    }

    public void send(String from, String to, String title, String text) throws MessagingException {
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(title);
        helper.setText(text, true);
        mailSender.send(message);
    }

}
